#include "dinput.h"
#include "..\common\def.h"
#include "..\engine\engine.h"

HRESULT CDInput9Device::CreateKeyboardDevice()
{
	try{
		CLog::Write("Creating keyboard device: "); 

		if(ISNULL(m_pDInput))
			throw EE_EXCEPTION("No input device")

		EE_ZEROMEMORY(m_prevKeyMap,sizeof(m_prevKeyMap)); 
		EE_ZEROMEMORY(m_keyMap,sizeof(m_keyMap)); 

		if(FAILED(m_pDInput->CreateDevice(GUID_SysKeyboard, &m_pKeyboardDevice, NULL)))
			throw EE_EXCEPTION("CreateDevice failed"); 

		if(FAILED(m_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard)))
			throw EE_EXCEPTION("SetDataFormat failed"); 

		if(FAILED(m_pKeyboardDevice->SetCooperativeLevel(CEngine::GetInstance()->GetWindow()->GetHWnd(), DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
			throw EE_EXCEPTION("SetCooperativeLevel failed"); 

		if(FAILED(m_pKeyboardDevice->Acquire())) 
			throw EE_EXCEPTION("Acquire failed"); 

		CLog::WriteLine("Success"); 
		return S_OK; 
	}
	catch(CError)
	{
		CError::LogError("Failed"); 
		m_pKeyboardDevice = NULL; 
		return E_FAIL; 
	}
}

HRESULT CDInput9Device::ReleaseKeyboardDevice()
{
	try{
		CLog::Write("Releasing keyboard device: "); 
		
		if(ISNULL(m_pKeyboardDevice))
		{
			CLog::Write("No keyboard device"); 
			return S_OK; 
		}

		if(FAILED(m_pKeyboardDevice->Unacquire()))
			EE_LOGERROR("Failed to unaquire keyboard device"); 

		if(FAILED(m_pKeyboardDevice->Release()))
		{
			EE_LOGERROR("Failed to Release keyboard device"); 
			return E_FAIL; 
		}

		m_pKeyboardDevice = NULL; 

		CLog::WriteLine("Success"); 
		return S_OK; 
	}
	catch(CError)
	{
		CLog::WriteLine("Failed"); 
		return E_FAIL; 
	}
}

void CDInput9Device::ResetKeyboardState()
{
	EE_ZEROMEMORY(m_prevKeyMap,sizeof(m_prevKeyMap)); 
	EE_ZEROMEMORY(&m_keyMap, sizeof(m_keyMap)); 
}

HRESULT	CDInput9Device::UpdateKeyboard(void)
{
	CopyMemory(m_prevKeyMap, m_keyMap, sizeof(m_prevKeyMap)); 

	switch(m_pKeyboardDevice->GetDeviceState(sizeof(m_keyMap), (LPVOID)&m_keyMap))
	{
		case DI_OK:
			{
				break; 
			}
		case DIERR_NOTINITIALIZED:
			{	
				if(FAILED(ReleaseKeyboardDevice()) || FAILED(CreateKeyboardDevice()))
					return E_FAIL; 
				break; 
			}
		case DIERR_INPUTLOST:
		case DIERR_NOTACQUIRED:
			{
				if(FAILED(m_pKeyboardDevice->Acquire()))
				{
					if(FAILED(ReleaseKeyboardDevice()) || FAILED(CreateKeyboardDevice()))
						return E_FAIL; 
				}
				break; 
			}
		default:
			{
				return E_FAIL; 
				break; 
			}
	}
	return S_OK; 
}

bool CDInput9Device::isKeyDown(const int  key)
{ 
	if((m_keyMap[key] & 0x80))
	{
		return true; 
	}
	return false; 
}

bool CDInput9Device::isKeyUp(const int  key) 
{ 
	if(!(m_keyMap[key] & 0x80))
	{
		return true; 
	}
	return false; 
}

bool CDInput9Device::isKeyReleased(const int  key)
{
	bool currentState = !((m_keyMap[key] & 0x80) == 0x80); 
	bool prevState = ((m_prevKeyMap[key] & 0x80) == 0x80); 

	return(currentState && prevState); 
}

bool CDInput9Device::isKeyPressed(const int  key)
{
	bool currentState = ((m_keyMap[key] & 0x80) == 0x80); 
	bool prevState = !((m_prevKeyMap[key] & 0x80) == 0x80); 

	return(currentState && prevState); 
}

char* CDInput9Device::getKeyMap(void) 
{ 
	return &m_keyMap[0];  
}

char* CDInput9Device::getPrevKeyMap(void) 
{ 
	return &m_prevKeyMap[0];  
}